package dao

import (
	"errors"
	"fmt"
	"log"
	"regexp"
	"time"
	"user-srv/basic/config"
	__ "user-srv/basic/proto"
	"user-srv/handler/models"
	"user-srv/pkg"
)

// 用户注册
func Register(in *__.CreateUserReq) (*models.User, error) {
	var user models.User
	mobileRegex := regexp.MustCompile(config.MobileRegex)
	if !mobileRegex.MatchString(in.Mobile) {
		return nil, errors.New("手机号格式错误")
	}
	user.Mobile = in.Mobile
	err := user.GetUserInfoByMobile(in.Mobile)
	if err != nil {
		return nil, fmt.Errorf("手机号查找用户失败")
	}
	if user.Id > 0 {
		return nil, fmt.Errorf("该手机号已被注册")
	}

	if len(in.Password) < config.PasswordLength {
		return nil, fmt.Errorf("密码不能小于5位")
	}

	hasUpper := regexp.MustCompile(config.HasUpper).MatchString(in.Password)
	if !hasUpper {
		return nil, fmt.Errorf("密码必须包含大写字母")
	}
	hasLower := regexp.MustCompile(config.HasLower).MatchString(in.Password)
	if !hasLower {
		return nil, fmt.Errorf("密码必须包含小写字母")
	}

	user.Password = pkg.DoubleMD5Encrypt(in.Password)

	if len(in.Nickname) > config.NicknameLength {
		return nil, fmt.Errorf("昵称不能大于5个字符")
	}
	user.Nickname = in.Nickname

	if err = user.CreateUser(); err != nil {
		return nil, fmt.Errorf(err.Error())
	}
	return &user, nil
}

// 用户登录
func Login(in *__.LoginReq) (*models.User, error) {
	var user models.User
	user.Mobile = in.Mobile
	err := user.GetUserInfoByMobile(in.Mobile)
	if err != nil {
		return nil, fmt.Errorf("手机号查找用户失败")
	}
	if user.Id == 0 {
		return nil, fmt.Errorf("该手机号未注册")
	}

	if user.Password != pkg.DoubleMD5Encrypt(in.Password) {
		return nil, fmt.Errorf("密码错误")
	}
	//面容id
	var face models.Face
	face.UserId = int32(user.Id)
	if err = face.GetFaceByUserId(); err != nil {
		return nil, errors.New("用户未绑定面容")
	}
	if face.Id == 0 {
		log.Printf("用户未绑定面容")
	} else {
		log.Printf("用户%v已存在面容id:%v", user.Id, face.Id)
	}
	// 用户登录计数和勋章解锁逻辑
	user.LoginCount++ // 增加用户登录次数
	fmt.Printf("用户 %d 登录次数: %d\n", user.Id, user.LoginCount)

	// 更新用户登录次数到数据库
	err = user.UpdateLoginCount()
	if err != nil {
		fmt.Printf("更新登录次数失败: %v\n", err)
	}

	// 检查是否解锁勋章
	var userBadges models.UserBadges
	if user.LoginCount >= 1 && user.LoginCount < 2 {
		// 首次登录解锁"初来乍到"勋章
		userBadges.UserId = uint64(user.Id)
		userBadges.RulesId = 1 // 假设规则ID 1 对应"初来乍到"勋章
		userBadges.Status = 1
		err = userBadges.UserBadgesUpdate()
		userBadges.ObtainedAt = time.Now()
		if err != nil {
			fmt.Printf("解锁'初来乍到'勋章失败: %v\n", err)
		} else {
			fmt.Println("解锁勋章: 初来乍到 (完成首次登录)")
		}
	} else if user.LoginCount >= 5 {
		// 登录5次解锁"常客"勋章
		userBadges.UserId = uint64(user.Id)
		userBadges.RulesId = 2 // 假设规则ID 2 对应"常客"勋章
		userBadges.Status = 1
		err = userBadges.UserBadgesUpdate()
		userBadges.ObtainedAt = time.Now()
		if err != nil {
			fmt.Printf("解锁'常客'勋章失败: %v\n", err)
		} else {
			fmt.Println("解锁勋章: 常客 (累计登录5次)")
		}
	}

	return &user, nil
}

// 用户注销
func UserDel(in *__.UserDelReq) (*models.User, error) {
	var user models.User
	user.Id = uint32(in.Id)
	err := user.GetUserInfoById(int(in.Id))
	if err != nil {
		return nil, fmt.Errorf("查找用户失败")
	}
	if user.Id == 0 {
		return nil, fmt.Errorf("用户不存在")
	}

	err = user.UserDel()
	if err != nil {
		return nil, fmt.Errorf("用户注销失败")
	}
	return &user, nil
}

// 用户修改密码
func UserUpdatePassword(in *__.UserUpdatePasswordReq) (*models.User, error) {
	var user models.User
	user.Id = uint32(in.Id)
	err := user.GetUserInfoById(int(in.Id))
	if err != nil {
		return nil, fmt.Errorf("查找用户失败")
	}
	if user.Id == 0 {
		return nil, fmt.Errorf("用户不存在")
	}

	if user.Password != pkg.DoubleMD5Encrypt(in.Password) {
		return nil, fmt.Errorf("旧密码输入错误")
	}

	if len(in.Password) < config.PasswordLength {
		return nil, fmt.Errorf("密码不能小于5位")
	}

	hasUpper := regexp.MustCompile(config.HasUpper).MatchString(in.Password)
	if !hasUpper {
		return nil, fmt.Errorf("密码必须包含大写字母")
	}
	hasLower := regexp.MustCompile(config.HasLower).MatchString(in.Password)
	if !hasLower {
		return nil, fmt.Errorf("密码必须包含小写字母")
	}

	if in.NewPassword != in.RePassword {
		return nil, fmt.Errorf("两次输入的密码不一致")
	}
	user.Id = uint32(in.Id)
	user.Password = pkg.DoubleMD5Encrypt(in.RePassword)
	err = user.UserUpdatePassword()
	if err != nil {
		return nil, fmt.Errorf("密码修改失败")
	}

	return &user, nil
}
